/**
 * This code is the utilities for spaghetti.
 * 
 * @author Jack
 * @version 1.0
 */
dojo.provide("spaghetti.utility");
dojo.require("dojo.string");


//---------------------------------------
// Utility methods.

/*TimeOut handle*/ spaghetti.setTimeOut = function(/*Object*/ scope, /*Function*/ callback, /*Number*/ time, /*Array*/ args){
	//	summary:
	//		The wrapper function for javascript function setTimeout.
	
	var s = scope ? scope : dojo.global; 
	return setTimeout(dojo.hitch(s, callback), time, args);
};

spaghetti.clearTimeOut = function(/*TimeOut handle*/ handle){
	//	summary:
	//		The wrapper function for javascript function clearTimeout.
	clearTimeout(handle);
}

spaghetti.notImplement = function(/*String*/ method){
	throw new Error(dojo.string.substitute("${0} is not implemented yet.", [method]));
};

/*Boolean*/ spaghetti.isNull = function(/*Object*/ obj){
	//	summary:
	//		The utility method to test if the object is null or the object is undefined.
	
	return (typeof obj == "undefined") || obj === null;
}

/*String[]*/ spaghetti.getPropertyNames = function(/*Object*/ obj){
	//	summary:
	//		Get all the property names in the object. Just data property, exclude function 
	//		and dojo class meta data.
	
	var ps = [];
	for(var p in obj){
		// Spare function
		if(typeof obj[p] == "function"){
			continue;
		}
		
		// Spare preamble
		if(p == "preamble"){
			continue;
		}
		
		// Spare declearedClass
		if(p == "declaredClass"){
			continue;
		}
		ps.push(p);
	}
	return ps;
}

/*Object*/ spaghetti.toJson = function(/*Object*/ obj, /*Function || null*/ exclude){
	//	summary:
	//		The utility method to make a shallow clone of the object for data transfer.
	//		Iterate in all its properties, can use a filter.
	//	obj:
	//		The object to clone
	//
	//	exclude:
	//		The filter method for clone.
	
	var o = {};
	dojo.forEach(spaghetti.getPropertyNames(obj), function(p){
		if(!spaghetti.isNull(exclude) && exclude(p)){
			return;
		}
		o[p] = obj[p];
	});
	return o;
}